package repository

import (
	"fitness/go-admin/internal/model"

	"gorm.io/gorm"
)

// ReviewRepository 评价仓储接口
type ReviewRepository interface {
	// 课程评价管理
	CreateCourseReview(review *model.CourseReview) error
	GetCourseReviewByID(id uint) (*model.CourseReview, error)
	GetCourseReviewsByCourseID(courseID uint, req *model.CourseReviewListReq) ([]model.CourseReview, int64, error)
	UpdateCourseReview(review *model.CourseReview) error
	DeleteCourseReview(id uint) error
	GetCourseReviewSummary(courseID uint) (map[int]int64, float64, error)
	GetReviewHelpfulCount(reviewID uint) (int64, error)
	GetUserHelpfulReview(userID, reviewID uint) (*model.ReviewHelpful, error)
	CreateReviewHelpful(helpful *model.ReviewHelpful) error
	DeleteReviewHelpful(id uint) error

	// 教练评分管理
	CreateCoachRating(rating *model.CoachRating) error
	GetCoachRatingByID(id uint) (*model.CoachRating, error)
	GetCoachRatingsByCoachID(coachID uint, req *model.CoachRatingListReq) ([]model.CoachRating, int64, error)
	GetCoachRatingSummary(coachID uint) (float64, float64, float64, float64, float64, int64, error)

	// 意见反馈管理
	CreateFeedback(feedback *model.Feedback) error
	GetFeedbackByID(id uint) (*model.Feedback, error)
	GetFeedbacks(req *model.FeedbackListReq) ([]model.Feedback, int64, error)
	GetUserFeedbacks(userID uint) ([]model.Feedback, error)
	UpdateFeedback(feedback *model.Feedback) error
	DeleteFeedback(id uint) error

	// 评价回复管理
	CreateReviewReply(reply *model.ReviewReply) error
	GetReviewReplies(reviewID uint, reviewType string) ([]model.ReviewReply, error)
	UpdateReviewReply(reply *model.ReviewReply) error
	DeleteReviewReply(id uint) error

	// 评价举报管理
	CreateReviewReport(report *model.ReviewReport) error
	GetReviewReportByID(id uint) (*model.ReviewReport, error)
	GetReviewReports(req *model.ReviewReportListReq) ([]model.ReviewReport, int64, error)
	UpdateReviewReport(report *model.ReviewReport) error
	DeleteReviewReport(id uint) error
}

type reviewRepository struct {
	db *gorm.DB
}

func NewReviewRepository(db *gorm.DB) ReviewRepository {
	return &reviewRepository{db: db}
}

// ==================== 课程评价管理 ====================

func (r *reviewRepository) CreateCourseReview(review *model.CourseReview) error {
	return r.db.Create(review).Error
}

func (r *reviewRepository) GetCourseReviewByID(id uint) (*model.CourseReview, error) {
	var review model.CourseReview
	err := r.db.Preload("User").Preload("Course").First(&review, id).Error
	return &review, err
}

func (r *reviewRepository) GetCourseReviewsByCourseID(courseID uint, req *model.CourseReviewListReq) ([]model.CourseReview, int64, error) {
	var reviews []model.CourseReview
	var total int64

	query := r.db.Model(&model.CourseReview{}).Where("course_id = ? AND status = ?", courseID, "APPROVED")

	// 条件筛选
	if req.Rating != nil {
		query = query.Where("rating = ?", *req.Rating)
	}

	if req.HasImages != nil && *req.HasImages {
		query = query.Where("images IS NOT NULL AND images != '' AND images != '[]'")
	}

	// 统计总数
	if err := query.Count(&total).Error; err != nil {
		return nil, 0, err
	}

	// 排序
	switch req.Sort {
	case "rating":
		query = query.Order("rating DESC")
	case "helpful":
		query = query.Order("helpful_count DESC")
	default:
		query = query.Order("created_at DESC")
	}

	// 分页
	offset := (req.Page - 1) * req.PageSize
	err := query.Preload("User").Limit(req.PageSize).Offset(offset).Find(&reviews).Error
	return reviews, total, err
}

func (r *reviewRepository) UpdateCourseReview(review *model.CourseReview) error {
	return r.db.Save(review).Error
}

func (r *reviewRepository) DeleteCourseReview(id uint) error {
	return r.db.Delete(&model.CourseReview{}, id).Error
}

func (r *reviewRepository) GetCourseReviewSummary(courseID uint) (map[int]int64, float64, error) {
	type RatingCount struct {
		Rating int
		Count  int64
	}

	var results []RatingCount
	err := r.db.Model(&model.CourseReview{}).
		Select("rating, COUNT(*) as count").
		Where("course_id = ? AND status = ?", courseID, "APPROVED").
		Group("rating").
		Scan(&results).Error

	if err != nil {
		return nil, 0, err
	}

	// 构建评分分布
	ratingDistribution := make(map[int]int64)
	for i := 1; i <= 5; i++ {
		ratingDistribution[i] = 0
	}

	var totalCount int64
	var totalRating float64

	for _, result := range results {
		ratingDistribution[result.Rating] = result.Count
		totalCount += result.Count
		totalRating += float64(result.Rating) * float64(result.Count)
	}

	avgRating := 0.0
	if totalCount > 0 {
		avgRating = totalRating / float64(totalCount)
	}

	return ratingDistribution, avgRating, nil
}

func (r *reviewRepository) GetReviewHelpfulCount(reviewID uint) (int64, error) {
	var count int64
	err := r.db.Model(&model.ReviewHelpful{}).Where("review_id = ?", reviewID).Count(&count).Error
	return count, err
}

func (r *reviewRepository) GetUserHelpfulReview(userID, reviewID uint) (*model.ReviewHelpful, error) {
	var helpful model.ReviewHelpful
	err := r.db.Where("user_id = ? AND review_id = ?", userID, reviewID).First(&helpful).Error
	return &helpful, err
}

func (r *reviewRepository) CreateReviewHelpful(helpful *model.ReviewHelpful) error {
	return r.db.Create(helpful).Error
}

func (r *reviewRepository) DeleteReviewHelpful(id uint) error {
	return r.db.Delete(&model.ReviewHelpful{}, id).Error
}

// ==================== 教练评分管理 ====================

func (r *reviewRepository) CreateCoachRating(rating *model.CoachRating) error {
	return r.db.Create(rating).Error
}

func (r *reviewRepository) GetCoachRatingByID(id uint) (*model.CoachRating, error) {
	var rating model.CoachRating
	err := r.db.Preload("User").Preload("Coach").First(&rating, id).Error
	return &rating, err
}

func (r *reviewRepository) GetCoachRatingsByCoachID(coachID uint, req *model.CoachRatingListReq) ([]model.CoachRating, int64, error) {
	var ratings []model.CoachRating
	var total int64

	query := r.db.Model(&model.CoachRating{}).Where("coach_id = ?", coachID)

	// 统计总数
	if err := query.Count(&total).Error; err != nil {
		return nil, 0, err
	}

	// 排序和分页
	offset := (req.Page - 1) * req.PageSize
	err := query.Preload("User").Order("created_at DESC").Limit(req.PageSize).Offset(offset).Find(&ratings).Error
	return ratings, total, err
}

func (r *reviewRepository) GetCoachRatingSummary(coachID uint) (float64, float64, float64, float64, float64, int64, error) {
	type Summary struct {
		TotalCount         int64
		AvgOverall         float64
		AvgProfessionalism *float64
		AvgPatience        *float64
		AvgEnthusiasm      *float64
		AvgCommunication   *float64
	}

	var summary Summary
	err := r.db.Model(&model.CoachRating{}).
		Select(`COUNT(*) as total_count,
				AVG(overall_rating) as avg_overall,
				AVG(professionalism) as avg_professionalism,
				AVG(patience) as avg_patience,
				AVG(enthusiasm) as avg_enthusiasm,
				AVG(communication) as avg_communication`).
		Where("coach_id = ?", coachID).
		Scan(&summary).Error

	if err != nil {
		return 0, 0, 0, 0, 0, 0, err
	}

	// 处理可能为null的字段
	var avgProfessionalism, avgPatience, avgEnthusiasm, avgCommunication float64
	if summary.AvgProfessionalism != nil {
		avgProfessionalism = *summary.AvgProfessionalism
	}
	if summary.AvgPatience != nil {
		avgPatience = *summary.AvgPatience
	}
	if summary.AvgEnthusiasm != nil {
		avgEnthusiasm = *summary.AvgEnthusiasm
	}
	if summary.AvgCommunication != nil {
		avgCommunication = *summary.AvgCommunication
	}

	return summary.AvgOverall, avgProfessionalism, avgPatience, avgEnthusiasm, avgCommunication, summary.TotalCount, nil
}

// ==================== 意见反馈管理 ====================

func (r *reviewRepository) CreateFeedback(feedback *model.Feedback) error {
	return r.db.Create(feedback).Error
}

func (r *reviewRepository) GetFeedbackByID(id uint) (*model.Feedback, error) {
	var feedback model.Feedback
	err := r.db.Preload("User").Preload("Handler").First(&feedback, id).Error
	return &feedback, err
}

func (r *reviewRepository) GetFeedbacks(req *model.FeedbackListReq) ([]model.Feedback, int64, error) {
	var feedbacks []model.Feedback
	var total int64

	query := r.db.Model(&model.Feedback{})

	// 条件筛选
	if req.Type != "" {
		query = query.Where("type = ?", req.Type)
	}
	if req.Status != "" {
		query = query.Where("status = ?", req.Status)
	}
	if req.Priority != "" {
		query = query.Where("priority = ?", req.Priority)
	}

	// 统计总数
	if err := query.Count(&total).Error; err != nil {
		return nil, 0, err
	}

	// 排序和分页
	offset := (req.Page - 1) * req.PageSize
	err := query.Preload("User").Preload("Handler").Order("created_at DESC").Limit(req.PageSize).Offset(offset).Find(&feedbacks).Error
	return feedbacks, total, err
}

func (r *reviewRepository) GetUserFeedbacks(userID uint) ([]model.Feedback, error) {
	var feedbacks []model.Feedback
	err := r.db.Where("user_id = ?", userID).Order("created_at DESC").Find(&feedbacks).Error
	return feedbacks, err
}

func (r *reviewRepository) UpdateFeedback(feedback *model.Feedback) error {
	return r.db.Save(feedback).Error
}

func (r *reviewRepository) DeleteFeedback(id uint) error {
	return r.db.Delete(&model.Feedback{}, id).Error
}

// ==================== 评价回复管理 ====================

func (r *reviewRepository) CreateReviewReply(reply *model.ReviewReply) error {
	return r.db.Create(reply).Error
}

func (r *reviewRepository) GetReviewReplies(reviewID uint, reviewType string) ([]model.ReviewReply, error) {
	var replies []model.ReviewReply
	err := r.db.Where("review_id = ? AND review_type = ?", reviewID, reviewType).
		Preload("User").
		Order("created_at ASC").
		Find(&replies).Error
	return replies, err
}

func (r *reviewRepository) UpdateReviewReply(reply *model.ReviewReply) error {
	return r.db.Save(reply).Error
}

func (r *reviewRepository) DeleteReviewReply(id uint) error {
	return r.db.Delete(&model.ReviewReply{}, id).Error
}

// ==================== 评价举报管理 ====================

func (r *reviewRepository) CreateReviewReport(report *model.ReviewReport) error {
	return r.db.Create(report).Error
}

func (r *reviewRepository) GetReviewReportByID(id uint) (*model.ReviewReport, error) {
	var report model.ReviewReport
	err := r.db.Preload("User").Preload("Review").Preload("Handler").First(&report, id).Error
	return &report, err
}

func (r *reviewRepository) GetReviewReports(req *model.ReviewReportListReq) ([]model.ReviewReport, int64, error) {
	var reports []model.ReviewReport
	var total int64

	query := r.db.Model(&model.ReviewReport{})

	// 条件筛选
	if req.Status != "" {
		query = query.Where("status = ?", req.Status)
	}

	// 统计总数
	if err := query.Count(&total).Error; err != nil {
		return nil, 0, err
	}

	// 排序和分页
	offset := (req.Page - 1) * req.PageSize
	err := query.Preload("User").Preload("Review").Preload("Handler").Order("created_at DESC").Limit(req.PageSize).Offset(offset).Find(&reports).Error
	return reports, total, err
}

func (r *reviewRepository) UpdateReviewReport(report *model.ReviewReport) error {
	return r.db.Save(report).Error
}

func (r *reviewRepository) DeleteReviewReport(id uint) error {
	return r.db.Delete(&model.ReviewReport{}, id).Error
}
